Lesson 4: if/then/else and loop structures
By Moyack


These kind of structures are the most important in any programming language. In JASS, these structures are quite versatile and useful.

Let's see the first structure: IF/THEN/ELSE

To work with it, we can write it in this way.

if/then/else structure


if <condition 1 function or variable> then

<Condition 1 script>
elseif <condition 2 function or variable> then
<Condition 2 script>
...
else
<Else condition script>
endif


Now you understand why I said versatile :)

As you can see, the conditions must be a function which has to return a boolean variable type (true/false) or a boolean variable. Other interesting feature with the if/then/else structure in JASS, is that it can be used as a multiselection structure too, something very useful in many cases.

In order to ensure the understanding of this structure, This is a small example showing the IF/THEN/ELSE in action

IF/THEN/ELSE example

function Set_Damage_To_Unit takes integer level returns real
// this example will set the damage amount in a spell, according to a level
// (unit level, ability level, etc)
local real dam
if level < 2 then
set dam = 0
elseif level == 1 then
set dam = 50.
// probably you noticed the point after the number. this is used to indicate the number is a real.
// Is a good programming practice to do that in order to avoid annoying debugging mistakes.
elseif level == 2 then
set dam = 63.
elseif level == 3 then
set dam = 125.
else
set dam = 125. + 50. * (level - 1)
return dam
endfunction


Here we are using a local variable which will have a value according to the input argument in the function, and then that variable will be returned by the function.

Important note

If any IF or ELSEIF clauses apply, then the ELSE clause will be avoided. This example function has a bug by purpose, in order to show an IF/THEN/ELSE characteristic. if level = 1, then the first clause will be executed (set dam = 0). Then the second condition will be executed and will be true too (elseif level == 1), then it will execute the second clause (set dam = 50). With that we can see that the IFTHENELSE structure can be used to make data filtering, for instance.


Another Important Note

The '=' character is used when setting a value, the '==' operator is used when comparing values. In other words, don't do: if x = 5 then... because Wc3 can't read your mind as to what you want it to really do. This line is saying to the computer "if (set x = 5) then..." and I don't think that makes much sense, how about you?

Now let's see the LOOP structure.

Loops in programming are used to make a set of instructions to be executed several times, loops can be classified by finite and infinite. The finite loops are which have a defined a fixed number of repetitive executions, controlled by an exit control. The Infinite loops in the other hand, will execute the script contained in it indefinitely.

The loop structure is as following:

loop
//Here you can put code too :)
exitwhen <condition function or variable>
//your iterative script
endloop


This structure is quite flexible as you can see, because you can put the exitwhen condition in ANY place inside the loop. Let's see an example.

Loop Example

function Heal_Unit_Group takes group g returns nothing
// this example will heal all units in a unit group.
local unit u // a local unit variable
loop
set u = FirstOfGroup(g) //Selects the first unit in the group.
exitwhen u == null // the loop will finish when the group will be empty,
// in tother words, when the FirstOfGroup() function returns null
call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE))
//sets the life of the selected unit at its maximum.
call GroupRemoveUnit(g, u) // removes the unit from the group
endloop
call DestroyGroup(g) // to avoid group leaks, we must destroy the group variable.
endfunction



The usage of FirstOfGroup and group functions inside a loop is very common in AOE spells, with them we can do several things to a unit group.

Some tips with loops

Sometimes, we want to use the loops as a way to do a mass effect spell. If you want to add special effects inside a loop, there is a big chance the code will lag, in order to avoid that, you should use a TriggerSleepAction() function, which will give to the WC3 engine a small break to process other tasks.

You can create an infinite and unstoppable loop using only the loop and endloop instructions without an exitwhen command.



Exercise

Create a function which displays all the numbers which can divide perfectly a given number. The function should be in that way:

function DivideNumbers takes integer n returns nothing
// your code here
endfunction


For exaple, if we make

DivideNumbers(12)

we should see on the game screen something like this:

1, 2, 3, 4, 6, 12

-Also, it would be helpful to tell you about the ModoloInteger function. This function returns the remainder of a division. So ModoloInteger(10, 3) would return 1.

Good luck